package com.cip.admin.service.impl;

import com.cip.admin.model.EmailConfig;
import com.cip.admin.service.EmailService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.AddressException;

import org.apache.velocity.app.VelocityEngine;

import com.cip.admin.dao.EmailDAO;
import com.cip.common.Constants;
import com.cip.common.util.CommonUtil;
import com.cip.common.util.GridUtil;

public class EmailServiceImpl implements EmailService {

	private EmailDAO emailDAO;
	private VelocityEngine velocityEngine;

	public Boolean sendEmail(String recipients, String body, String subject)
			throws MessagingException {
		try {

			Message message = new MimeMessage(getSession());
			message.setFrom(new InternetAddress(Constants.EMAIL_UNAME));
			if (recipients.contains(",")) {
				InternetAddress[] addressTo = convertToInternetAddress(recipients);
				message.addRecipients(Message.RecipientType.TO, addressTo);
			} else {
				message.addRecipient(Message.RecipientType.TO,
						new InternetAddress(recipients));
			}
			message.setSubject(subject);
			message.setContent(body, "text/html");
			Transport.send(message);
		} catch (MessagingException me) {
			throw new MessagingException(me.getMessage(), me);
		}
		return true;
	}
	
	
	public String getEmailConfigGridList(Locale locale)throws Exception {
		
		String gridSource = ""; 
		
		try {
			List<EmailConfig> emailConfigList = getAllEmaillConfigList();
			
			List<Map<String,Object>> emailConfigArrayList = new ArrayList<Map<String,Object>>();
			
			System.out.println("instList============="+emailConfigList);
			
			for (EmailConfig emailConfig : emailConfigList) {
				Map<String,Object> emailConfigObj = new HashMap<String, Object>();
				emailConfigObj.put("serverName", "<a href='/editEmailConfig?method=showEditEmailConfig&emailConfig.id=="+emailConfig.getId()+"' style='text-decoration:underline;color:blue;'>"+emailConfig.getServerName()+"</a>");
				emailConfigObj.put("inboundAuthentication", emailConfig.getInboundAuthentication());
				emailConfigObj.put("portNo", emailConfig.getPortNo());
				emailConfigObj.put("sslRequired", emailConfig.getSslRequired());
				emailConfigObj.put("status", emailConfig.getStatus());
				
				System.out.println("instArray================"+emailConfigObj);
				
				emailConfigArrayList.add(emailConfigObj);			
			}
			
			System.out.println("instArrayList=========="+emailConfigList);
			
			gridSource = generateScriptForProcess(velocityEngine, emailConfigArrayList, locale);
			
			System.out.println("gridSource===================="+gridSource);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return gridSource;
	}
	
	/**
	 * Set into context of grid column names and field names and it attributes
	 * 
	 * @param context
	 * @return
	 * @throws Exception
	 */
	public static String generateScriptForProcess(VelocityEngine velocityEngine, List<Map<String, Object>> emailConfigList, Locale locale) throws Exception {
		
		System.out.println("instArrayList========="+emailConfigList);
		System.out.println("locale========="+locale);

		return GridUtil.generateScriptForProcess(velocityEngine, emailConfigList, createMyEmailConfigGridColumnMapping(locale));
		
	}
	
	/**
	 * Add needed column and it mapping for my instances
	 * 
	 * @param context
	 */
	private static Map<String, Object> createMyEmailConfigGridColumnMapping(Locale locale) {
		Map<String, Object> context = new HashMap<String, Object>();
		List<Map<String, Object>> fieldNameList = new ArrayList<Map<String, Object>>();
		//ResourceBundle appResourceBundle = ResourceBundle.getBundle(Constants.BUNDLE_KEY ,locale);
		//context.put("title", appResourceBundle.getString("process.myInstances"));
		context.put("title", "Email Configuration List");
		context.put("gridId", "MY_EMAILCONFIG");
		context.put("needTreeStructure", true);
		//context.put("dynamicGridWidth", "300px");
		//context.put("dynamicGridHeight", "580px");
		String columnNames = "['Server Name','Inbound Authentication','Port No','SSL Required','Status']";
        CommonUtil.createFieldNameList(fieldNameList, "serverName", "100", "center", "","false");
        CommonUtil.createFieldNameList(fieldNameList, "inboundAuthentication", "70", "left","", "false");
        CommonUtil.createFieldNameList(fieldNameList, "portNo", "50","left", "", "false");
        CommonUtil.createFieldNameList(fieldNameList, "sslRequired", "70", "center", "", "false");
        CommonUtil.createFieldNameList(fieldNameList, "status", "70", "center", "", "false");

        context.put("columnNames", columnNames);
        context.put("noOfRecords", "10");
		context.put("fieldNameList", fieldNameList);
		context.put("gridHeading", "true");
		
		System.out.println("context====================="+context);
		
		return context;
	}
	
	
	private Session getSession() {
		String host = "smtp.gmail.com";
		String smtpPort = "465";
		String isSSLRequired = "true";
		Authenticator authenticator = new Authenticator();
		Properties properties = new Properties();
		if ("true".equalsIgnoreCase(isSSLRequired)) {
			properties.setProperty("mail.smtp.submitter", authenticator.getPasswordAuthentication().getUserName());
			properties.setProperty("mail.smtp.auth", "true");
			properties.setProperty("mail.smtp.host", host);
			properties.setProperty("mail.smtp.port", smtpPort);
			properties.put("mail.smtp.socketFactory.port", smtpPort);
			// Security.addProvider(new
			// com.sun.net.ssl.internal.ssl.Provider());
			properties.setProperty("mail.transport.protocol", "smtp");
			properties.put("mail.smtp.socketFactory.class",
					"javax.net.ssl.SSLSocketFactory");
			properties.put("mail.smtp.socketFactory.fallback", "false");
			properties.setProperty("mail.smtp.quitwait", "false");
			return Session.getInstance(properties, authenticator);
		} else {
			properties.put("mail.smtp.host", host);
			properties.put("mail.smtp.port", smtpPort);
			return Session.getDefaultInstance(properties);
		}
	}

	private InternetAddress[] convertToInternetAddress(String recipients) {
		StringTokenizer addresses = new StringTokenizer(recipients, ",");
		String[] recipientIds = recipients.split(",");
		int i = 0;
		InternetAddress[] addressTo = new InternetAddress[recipientIds.length];
		while (addresses.hasMoreElements()) {
			String element = (String) addresses.nextElement();
			try {
				addressTo[i] = new InternetAddress(element);
			} catch (AddressException e) {
				continue;
			}
			i++;
		}
		return addressTo;
	}

	private class Authenticator extends javax.mail.Authenticator {

		private PasswordAuthentication authentication;

		public Authenticator() {
			String userName = Constants.EMAIL_UNAME;
			String password = Constants.EMAIL_PWORD;
			authentication = new PasswordAuthentication(userName, password);
		}

		protected PasswordAuthentication getPasswordAuthentication() {
			return authentication;
		}
	}

	
	public VelocityEngine getVelocityEngine() {
		return velocityEngine;
	}
	public void setVelocityEngine(VelocityEngine velocityEngine) {
		this.velocityEngine = velocityEngine;
	}
	public List<EmailConfig> getAllEmaillConfigList() throws Exception {
		return emailDAO.getAllEmaillConfigList();
	}

	public EmailConfig getEmailConfigById(int id) throws Exception {
		return emailDAO.getEmailConfigById(id);
	}

	public EmailConfig saveOrUpdateEmailConfig(EmailConfig emailConfig)
			throws Exception {
		return emailDAO.saveOrUpdateEmailConfig(emailConfig);
	}

	public EmailConfig editEmaillConfig(EmailConfig emailConfig) throws Exception {		
		return emailDAO.editEmailConfig(emailConfig);
	}

	public EmailDAO getEmailDAO() {
		return emailDAO;
	}

	public void setEmailDAO(EmailDAO emailDAO) {
		this.emailDAO = emailDAO;
	}

}
